//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "Globals.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
THexForm *HexForm;
//---------------------------------------------------------------------------
__fastcall THexForm::THexForm(TComponent* Owner)
 : TForm(Owner)
{
}

//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall THexForm::DrawHex( BYTE *String, bool flag )
{
  WORD x,
       y,
       ptr,
       fnHeight;
  char buf[16];

  if ( !rom.data ) return;

  memset( hxData, 0, 0x1000 );

  // GET the BYTE count
  hexx.posi = 0;
  count     = 0;
  while( count < 0x1000 && String[count] != 0xFF )
  { //
    hxData[ count ] = String[ count ];
    count++;
    if ( String[ count ] == 0xFF ){
      hxData[ count ] = String[ count ]; count++;
      break;
    }
  }

  //
  if ( !count && String[ count ] == 0xFF )
    hxData[ count ] = String[ count ]; count++;

  //
  fnHeight  = abs( HexForm->Font->Height ) + 2;
  //
  hexx.flag = flag;
  hexx.mx   = 16;
  hexx.my   = (HexForm->ClientHeight / fnHeight);
  // Re-adjust the window height
//  HexForm->ClientHeight = (hexx.my * fnHeight);
  //
  y   = -1;
  while( ++y < hexx.my )
  { //
    ptr = 0;
    x = -1;
    while( ++x < hexx.mx )
    { //
      sprintf( buf, "%02X", hxData[ hexx.posi + (y << 4) + x ] );
      //
      if ( x == hexx.x && y == hexx.y )
      { //
        HexForm->Canvas->Font->Color = clRed;
        SetBkColor( HexForm->Canvas->Handle, clWhite);
      }
      else
      { //
        HexForm->Canvas->Font->Color = ( x & 1 ) ? clWhite : clTeal;
        SetBkColor( HexForm->Canvas->Handle, clBlack );
      }

      //
			 HexForm->Canvas->TextOut( ptr, (y * fnHeight), buf );
      ptr += HexForm->Canvas->TextWidth( AnsiString(buf) );
    }
  }
  //
  DrawPic( flag );
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall THexForm::UpdateHex( BYTE *String, bool flag )
{
  WORD x,
       y,
       ptr,
       fnHeight;
  char buf[16];

  if ( !rom.data ) return;
  //
  fnHeight  = abs( HexForm->Font->Height ) + 2;
  //
  hexx.flag = flag;
  hexx.mx   = 16;
  hexx.my   = (HexForm->ClientHeight / fnHeight);
  // Re-adjust the window height
//  HexForm->ClientHeight = (hexx.my * fnHeight);
  //
  y   = -1;
  while( ++y < hexx.my )
  { //
    ptr = 0;
    x = -1;
    while( ++x < hexx.mx )
    { //
      sprintf( buf, "%02X", hxData[ hexx.posi + (y << 4) + x ] );
      //
      if ( x == hexx.x && y == hexx.y )
      { //
        HexForm->Canvas->Font->Color = clRed;
        SetBkColor( HexForm->Canvas->Handle, clWhite);
      }
      else
      { //
        HexForm->Canvas->Font->Color = ( x & 1 ) ? clWhite : clTeal;
        SetBkColor( HexForm->Canvas->Handle, clBlack );
      }

      //
			 HexForm->Canvas->TextOut( ptr, (y * fnHeight), buf );
      ptr += HexForm->Canvas->TextWidth( AnsiString(buf) );
    }
  }
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall THexForm::FormCreate(TObject *Sender)
{
  hexx.mx = 0;
  hexx.my = 0;
  hexx.x  = 0;
  hexx.y  = 0;

  PIC = new Graphics::TBitmap;

  PIC->Width       = 16;
  PIC->Height      = 16;
  PIC->PixelFormat = pf16bit;

  iBeenHere = false;
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall THexForm::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
  switch( Key )
  {
    case VK_LEFT : if ( hexx.x > 0 ) hexx.x--; else { hexx.x = (hexx.mx-1); goto _Up; }   break;
    case VK_RIGHT: if ( hexx.x < (hexx.mx-1) ) hexx.x++; else { hexx.x = 0; goto _Down; } break;
    //------------
    case VK_UP   : _Up:
                    if ( hexx.y > 0 ){ hexx.y--; break; }
                    if ( !hexx.y  && hexx.posi ) hexx.posi -= hexx.mx;
                    break;
    //------------
    case VK_DOWN : _Down:
                  if ( hexx.y < (hexx.my-1) ){ hexx.y++; break; }
                  if ( hexx.y == (hexx.my-1) && (hexx.posi + hexx.mx) < 0x1000 ) hexx.posi += hexx.mx;
                  break;
    //----------------------
    default : return;
  }
  //
  UpdateHex( hxData, hexx.flag );
  DrawPic( hexx.flag );
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall THexForm::DrawPic( bool flag )
{
  LONG posi;
  BYTE TILE[16][16];
  WORD *VRAM;
  BYTE BUFR[0x20];

  if ( !rom.data ) return;

  txt.data = hxData[ hexx.posi + (hexx.y << 4) + hexx.x];
  // Check for Kanji
  if ( (txt.data & 0xF0 ) == 0xE0 ) {
    txt.data     = ((txt.data & 0x0F) << 8) + hxData[ hexx.posi + (hexx.y << 4) + (hexx.x + 1)];
    txt.data += 0x00E0;
//    txt.TextBuf += 1;
  }

  //-----------------------------//
  // Font size testing done here //
  //-----------------------------//
  if ( !myForm->DTT->Checked )
  { //
    // Display the text
    txt.tpos = txt.data;
    txt.tpos = WGET( rom.data, Snes2Pc( 0x8C9C00 + (txt.data << 1)) );
    //
    myForm->DecodeFont( Snes2Pc( 0x8C0000 + txt.tpos ), BUFR );
    // Convert the tile data
    int x = -1;
    while( ++x < 8 ){
      Dec2Bin( &txt.tile[ (x + 0x00) << 4 ], (BUFR[ x + 0x00 ] << 8) + BUFR[ x + 0x08], 16 );
      Dec2Bin( &txt.tile[ (x + 0x08) << 4 ], (BUFR[ x + 0x10 ] << 8) + BUFR[ x + 0x18], 16 );
    }
    //
  }
  else
  if ( flag || myForm->DTT->Checked )
  { // Last Transfer
    memcpy( BUFR, &FONT16x16[ (txt.data & 0xFF) << 5 ], 0x20 );
    memset( txt.tile, 0, 256 );
    // Convert the tile data
    int x = -1;
    while( ++x < 16 )
      Dec2Bin( &txt.tile[ x << 4 ], (BUFR[ x ] << 8) + BUFR[ x + 0x10 ], 16 );
    //
  }

  //---------------//
  // DMA to Vram   //
  //---------------//
  for ( int y = 0; y < 16; y++ )
  { //
    (void *)VRAM = PIC->ScanLine[ y ];
    for ( int x = 0; x < 16; x++ )
      VRAM[ x ] = DOS565[ txt.tile[ (y << 4) + x ] * 0x0F ];
  }
  //
//  HexForm->Canvas->StretchDraw( Rect( 264, 4, 390, 128 ), PIC );
  chPic->Canvas->StretchDraw( chPic->ClientRect, PIC );
  //
  // Display the Offset
  if ( (hexx.posi + (hexx.y << 4) + hexx.x) < (count-1) )
    HexForm->Caption = "Hex Data - $" + IntToHex( ((txt.posi & 0xFF8000) | txt.pntr) + (hexx.posi + (hexx.y << 4) + hexx.x), 8 );
  else
    HexForm->Caption = "Hex Data - $" + IntToHex( ((txt.posi & 0xFF8000) | txt.pntr) + (count-1), 8 );
}

//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall THexForm::FormPaint(TObject *Sender)
{
  UpdateHex( hxData, hexx.flag );
  DrawPic( hexx.flag );
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall THexForm::FormResize(TObject *Sender)
{
  FormPaint( Sender );
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall THexForm::FormKeyPress(TObject *Sender, char &Key)
{
  char *hexinfo = "0123456789ABCDEF";
  static char hexraw[3];

  if ( !rom.data || !ram || !iCanDraw ) return;
  //
  if ( strchr( hexinfo,toupper( Key ) ) )
  {
    if ( iBeenHere )
    {
      hexraw[1] = Key;
      hexraw[2] = 0;
      hxData[ hexx.posi + (hexx.y << 4) + hexx.x ] = strtoul( hexraw, NULL, 16 );
      //
      iBeenHere = false;
      Key       = 0;
      memset( hexraw, 0, 3 );
      //
      UpdateHex( hxData, hexx.flag );
      DrawPic( hexx.flag );
    }
    else
    {
      hexraw[0] = Key;
      iBeenHere = true;
      Key       = 0;
    }
  }
  else
  {
    memset( hexraw, 0, 3 );
    iBeenHere = false;
    Key       = 0;
  } // END IF
}


